package cn.test.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.test.constant.StockConstant;
import cn.test.service.UserService;
import cn.test.mapper.SysUserMapper;
import cn.test.pojo.entity.SysUser;
import cn.test.utils.IdWorker;
import cn.test.vo.req.LoginReqVo;
import cn.test.vo.resp.LoginRespVo;
import cn.test.vo.resp.R;
import cn.test.vo.resp.ResponseCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author bigBear
 * @version 1.0
 * @date 2024-10-16 20:48
 */
@Slf4j
@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 根据用户名查询用户信息
     *
     * @param userName 用户名称
     * @return
     */
    @Override
    public SysUser findByUserName(String userName) {
        return sysUserMapper.findByUserName(userName);
    }

    /**
     * 登录
     *
     * @param loginReqVo
     * @return
     */
    @Override
    public R<LoginRespVo> login(LoginReqVo loginReqVo) {
        //1.判断参数是否正确
        if (loginReqVo == null || StringUtils.isBlank(loginReqVo.getUsername()) || StringUtils.isBlank(loginReqVo.getPassword())) {
            return R.error(ResponseCode.DATA_ERROR); //参数异常
        }
        //验证码校验
        if (StringUtils.isBlank(loginReqVo.getCode())) {
            return R.error(ResponseCode.CHECK_CODE_NOT_EMPTY);
        }
        //获取redis中的验证码
        String redisCode = (String) redisTemplate.opsForValue().get(StockConstant.CHECK_PREFIX + loginReqVo.getSessionId());
        if (!redisCode.equalsIgnoreCase(loginReqVo.getCode())) {
            return R.error(ResponseCode.CHECK_CODE_ERROR);
        }
        //2.根据用户名查询用户信息
        SysUser sysUser = sysUserMapper.findByUserName(loginReqVo.getUsername());
        if (sysUser == null) {
            return R.error(ResponseCode.ACCOUNT_NOT_EXISTS); //该账号不存在
        }
        //3.比对密码是否正确
        String dbPwd = sysUser.getPassword();
        boolean matches = passwordEncoder.matches(loginReqVo.getPassword(), dbPwd);
        if (!matches) {
            return R.error(ResponseCode.USERNAME_OR_PASSWORD_ERROR); //用户名或密码错误
        }
        //4.响应
        LoginRespVo loginRespVo = new LoginRespVo();
        BeanUtils.copyProperties(sysUser, loginRespVo);
        return R.ok(loginRespVo);
    }

    /**
     * 生成登录验证码
     *
     * @return
     */
    @Override
    public R<Map> getCaptchaCode() {
        //宽、高、验证码长度、干扰线数量
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(250, 40, 4, 5);
        //设置背景颜色
        captcha.setBackground(Color.lightGray);
        //获取图片中的验证码，默认生成包含字母和数字，长度为4
        String checkCode = captcha.getCode();
        log.info("验证码：{}", checkCode);
        //生成sessionId
        String sessionId = String.valueOf(idWorker.nextId());
        //将验证码和sessionId存入redis，设置过期时间为1分钟
        redisTemplate.opsForValue().set(StockConstant.CHECK_PREFIX + sessionId, checkCode, 1, TimeUnit.MINUTES);
        //组装数据
        HashMap<String, String> data = new HashMap<>();
        data.put("sessionId", sessionId);
        data.put("imageData", captcha.getImageBase64());//获取base64格式的图片数据
        //响应
        return R.ok(data);
    }
}
















